(define (domain fetch_demo)

(:requirements :strips :typing :fluents :disjunctive-preconditions :durative-actions)

(:types
	waypoint 
	robot
    arm - robot
    table
    object 
    cube - object
)

(:predicates
	(robot_at ?v - robot ?wp - waypoint)
	(visited ?wp - waypoint)
    (closeto_table ?v - robot ?tb - table)
    (closeto_object ?a - arm ?cb - cube)
    (object_on_table ?cb - cube ?tb - table)
    (object_in_hand ?cb - cube ?a - robot)
    (arm_tucked ?a - arm)
    (gripper_open ?a - arm)
    (get_object ?v - fetch ?cb - cube)
    (release_object ?v - fetch ?cb - cube)
    ; (connected ?from ?to - waypoint)
    
    ; (caught_object ?a - arm ?cb - cube)
)

(:functions
	(distance ?wp1 ?wp2 - waypoint) 
)

;; Move between any two waypoints, avoiding terrain
(:durative-action moveto
	:parameters (?v - robot ?from ?to - waypoint ?a - arm, ?tb - table)
	:duration ( = ?duration 10)
	:condition (and
		(at start (robot_at ?v ?from)))
	:effect (and
		(at end (visited ?to))
		(at start (not (robot_at ?v ?from)))
		(at end (robot_at ?v ?to)))
        (at end (not (object_in_hand ?cb ?a)))
        (at end (closeto_table ?v ?tb))
)

(:durative-action moveto_with_object
    :parameters (?v - robot ?from ?to - waypoint ?a - arm, ?tb - table ?cb - object)
    :duration (= ?duration 10)
    :condition (and 
        (at start (robot_at ?v ?from))
        (at start (object_in_hand ?cb ?a)))
        (at start (gripper_close ?a))

    :effect (and 
        (at end (visited ?to))
		(at start (not (robot_at ?v ?from)))
		(at end (robot_at ?v ?to))
        (at end (object_in_hand ?cb ?a )))
        (at end (closeto_table ?v ?tb))
        (at end (gripper_close ?a))
        (at end (object_in_hand ?cb ?a))
)
   
(:action stratch_arm
    :parameters (?v - robot ?a - arm ?cb cube ?tb - table)
    :precondition (and 
        (closeto_table ?v ?tb)
        (not (closeto_object ?a ?cb))
        (not (object_in_hand ?cb ?a))
    )
    :effect (and 
        (closeto_object ?a ?cb)
        (not (object_in_hand ?cb ?a))
    )
)
    
(:action stratch_arm_with_object
    :parameters (?v - robot ?a - arm ?cb cube ?tb - table ?wp - waypoint)
    :precondition (and 
        (not (object_on_table ?cb ?tb))
        (object_in_hand ?cb ?a)
        (closeto_table ?v ?tb)
    )
    :effect (and 
        (not (object_on_table ?cb ?tb))
        (object_in_hand ?cb ?a)
        (visited ?wp)
    )
)

(:action tuck_arm
    :parameters (?v - robot ?a - arm ?cb cube ?tb - table)
    :precondition (and 
        (closeto_table ?v ?tb)
        (object_on_table ?cb ?tb)
        (not (object_in_hand ?cb ?a))
        (not (arm_tucked ?a))
    )
    :effect (and 
        (closeto_table ?v ?tb)
        (object_on_table ?cb ?tb)
        (not (object_in_hand ?cb ?a))
        (arm_tucked ?a)
    )
)

(:action tuck_arm_with_object
    :parameters (?v - robot ?a - arm ?cb cube ?tb - table)
    :precondition (and 
        (closeto_table ?v ?tb)
        (not (object_on_table ?cb ?tb))
        (object_in_hand ?cb ?a)
        (not (arm_tucked ?a))
    )
    :effect (and 
        (closeto_table ?v ?tb)
        (not (object_on_table ?cb ?tb))
        (object_in_hand ?cb ?a)
        (arm_tucked ?a)
    )
)

(:action grasp_object
    :parameters (?v - robot ?a - arm ?cb - cube ?tb - table)
    :precondition (and 
        (closeto_table ?v ?tb)
        (closeto_object ?a ?cb)
        (not (object_in_hand ?cb ?a))
        (gripper_open ?a)
    )
    :effect (and 
        (closeto_table ?v ?tb)
        (closeto_object ?a ?cb)
        (object_in_hand ?cb ?a)
        (not (gripper_open ?a))
    )
)

(:action release_object
    :parameters (?v - robot ?a - arm ?cb - cube ?tb - table)
    :precondition (and
        (closeto_table ?v ?tb)
        (object_in_hand ?cb ?a)
        (not (gripper_open ?a))
    )
    :effect (and 
        (closeto_table ?v ?tb)
        (not (object_in_hand ?cb ?a))
        (gripper_open ?a)
    )
)

)
